using TerritoryGame.Domain.ValueObjects;

namespace TerritoryGame.Domain.Services;

public interface IConflictResolutionService
{
    bool CanPaintAtPosition(Position position, int brushSize, PlayerColor color, Dictionary<Position, PlayerColor> pixels, int canvasWidth, int canvasHeight);
    List<Position> GetConflictingPixels(Position position, int brushSize, PlayerColor color, Dictionary<Position, PlayerColor> pixels);
    bool IsValidPaintAction(Position position, int brushSize, PlayerColor color, Dictionary<Position, PlayerColor> pixels, int canvasWidth, int canvasHeight);
    int CalculateEffectiveAreaChange(Position position, int brushSize, PlayerColor color, Dictionary<Position, PlayerColor> pixels);
}

public class ConflictResolutionService : IConflictResolutionService
{
    public bool CanPaintAtPosition(Position position, int brushSize, PlayerColor color, Dictionary<Position, PlayerColor> pixels, int canvasWidth, int canvasHeight)
    {
        // 检查边界
        if (!IsWithinCanvasBounds(position, brushSize, canvasWidth, canvasHeight))
            return false;

        // 检查冲突
        var conflictingPixels = GetConflictingPixels(position, brushSize, color, pixels);
        return conflictingPixels.Count == 0;
    }

    public List<Position> GetConflictingPixels(Position position, int brushSize, PlayerColor color, Dictionary<Position, PlayerColor> pixels)
    {
        var conflicts = new List<Position>();
        var affectedPixels = GetAffectedPixels(position, brushSize);

        foreach (var pixelPos in affectedPixels)
        {
            if (pixels.TryGetValue(pixelPos, out var existingColor) && existingColor != color)
            {
                conflicts.Add(pixelPos);
            }
        }

        return conflicts;
    }

    public bool IsValidPaintAction(Position position, int brushSize, PlayerColor color, Dictionary<Position, PlayerColor> pixels, int canvasWidth, int canvasHeight)
    {
        // 基本验证
        if (brushSize <= 0 || brushSize > 50) // 限制画笔大小
            return false;

        if (string.IsNullOrEmpty(color.Value))
            return false;

        // 检查是否可以涂色
        return CanPaintAtPosition(position, brushSize, color, pixels, canvasWidth, canvasHeight);
    }

    public int CalculateEffectiveAreaChange(Position position, int brushSize, PlayerColor color, Dictionary<Position, PlayerColor> pixels)
    {
        int areaChange = 0;
        var affectedPixels = GetAffectedPixels(position, brushSize);

        foreach (var pixelPos in affectedPixels)
        {
            // 只有在新涂色或覆盖自己的颜色时才计算面积变化
            if (!pixels.TryGetValue(pixelPos, out var existingColor) || existingColor == color)
            {
                areaChange++;
            }
        }

        return areaChange;
    }

    private bool IsWithinCanvasBounds(Position position, int brushSize, int canvasWidth, int canvasHeight)
    {
        int radius = brushSize / 2;
        
        // 检查画笔中心点
        if (!position.IsWithinBounds(canvasWidth, canvasHeight))
            return false;

        // 检查画笔边界
        var minX = position.X - radius;
        var maxX = position.X + radius;
        var minY = position.Y - radius;
        var maxY = position.Y + radius;

        return minX >= 0 && maxX < canvasWidth && minY >= 0 && maxY < canvasHeight;
    }

    private static IEnumerable<Position> GetAffectedPixels(Position center, int brushSize)
    {
        var pixels = new List<Position>();
        int radius = brushSize / 2;

        for (int x = center.X - radius; x <= center.X + radius; x++)
        {
            for (int y = center.Y - radius; y <= center.Y + radius; y++)
            {
                // 圆形画笔
                if (Math.Pow(x - center.X, 2) + Math.Pow(y - center.Y, 2) <= Math.Pow(radius, 2))
                {
                    pixels.Add(new Position(x, y));
                }
            }
        }

        return pixels;
    }
} 